package com.hqs.drawingboard;

import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * Created by super on 2017/7/4.
 */

public class TouchUtil {

    public static int duration = 200;
    public static int offsetTimestamp = 300;
    public static int maxPointerCount = 4;
    private static long startTimestamp;
    private static long touchDownTimestamp;
    private static long touchUpTimestamp;
    private static ArrayList<Integer> pointerArray = new ArrayList();

    private static float x;
    private static float y;
    private static HashMap<Integer, Integer> pMap = new HashMap<>();

    public static boolean onTouch(MotionEvent event, OnMultiClickListener multiClickListener, View view){

        if (multiClickListener == null){
            return false;
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN :

                touchDownTimestamp = System.currentTimeMillis();
                if (touchDownTimestamp - startTimestamp > duration && touchDownTimestamp - touchUpTimestamp > 200){
                    initStartTime();
                }
                pointerArray.clear();
                pointerArray.add(event.getPointerCount());

                x = event.getX();
                y = event.getY();
                break;
            case MotionEvent.ACTION_MOVE :
                float xx = event.getX();
                float yy = event.getY();
                float dis = (float) Math.pow((xx - x) * (xx - x) + (yy - y) * (yy - y), 0.5);
                if (dis < 2){
                    pointerArray.add(event.getPointerCount());
                }
                else{
                    pointerArray.clear();
                    return false;
                }
                break;
            case MotionEvent.ACTION_UP :
                pointerArray.add(event.getPointerCount());
                long curTime = System.currentTimeMillis();
                touchUpTimestamp = curTime;
                if (curTime - touchDownTimestamp < duration){
                    int type = clickType();
                    if (type != 0){
                        add2Task(type, multiClickListener, view);
                        return true;
                    }
                }
                break;
        }
        return false;
    }

    private static void initStartTime(){
        startTimestamp = System.currentTimeMillis();
        pMap.put(1, 0);
        pMap.put(2, 0);
        pMap.put(3, 0);
        pMap.put(4, 0);
    }

    private static void add2Task(final int type, final OnMultiClickListener multiClickListener, final View view){

        TaskHandle.getInstance().addTask(new Runnable() {
            @Override
            public void run() {
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        switch (type) {
                            case 11:
                                multiClickListener.onClick(view);
                                break;
                            case 12:
                                multiClickListener.onDoubleClick(view);
                                break;
                            case 13:
                                multiClickListener.onTrebleClick(view);
                                break;
                            case 21:
                                multiClickListener.on2Click(view);
                                break;
                            case 22:
                                multiClickListener.on2DoubleClick(view);
                                break;
                            case 23:
                                multiClickListener.on2TrebleClick(view);
                                break;
                            case 31:
                                multiClickListener.on3Click(view);
                                break;
                            case 32:
                                multiClickListener.on3DoubleClick(view);
                                break;
                            case 33:
                                multiClickListener.on3TrebleClick(view);
                                break;
                            case 41:
                                multiClickListener.on4Click(view);
                                break;
                            case 42:
                                multiClickListener.on4DoubleClick(view);
                                break;
                            case 43:
                                multiClickListener.on4TrebleClick(view);
                                break;

                        }
                    }
                });
            }
        });


    }

    private static int clickType(){

        if (pointerArray.size() > 1){
            if (pointerArray.get(0) == 1 && pointerArray.get(pointerArray.size() - 1) == 1){
                int base = 0;
                for (int i = 1; i < pointerArray.size() - 1; i++){

                    if (pointerArray.get(i) > base){
                        base = pointerArray.get(i);
                    }
                }
                for (int i : pointerArray){
                    if (i > base){
                        base = i;
                    }
                }
                if (base > maxPointerCount){
                    base = maxPointerCount;
                }
                return type(base);
            }
        }
        return 0;
    }

    private static int type(int base){
        int p = pMap.get(base);
        p += 1;

        if (p > 3){
            p = 3;
        }

        pMap.put(base, p);
        return 10 * base + p;
    }

    static class TaskHandle {

        private boolean isRunning = false;
        private Thread thread;
        private long timestamp;
        private static TaskHandle instance = new TaskHandle();
        private long lastTaskTimestamp;
        private Runnable task;

        private TaskHandle(){

        }

        public static TaskHandle getInstance() {
            instance.timestamp = System.currentTimeMillis();
            instance.task = null;
            if (instance.thread == null){
                instance.isRunning = true;
                instance.thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        while (instance.isRunning){
                            if (System.currentTimeMillis() - instance.timestamp > offsetTimestamp){
                                instance.runTask();
                            }
                            else{
                                try {
                                    Thread.sleep(10);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                });
                instance.thread.start();
            }
            return instance;
        }

        void addTask(Runnable task){
            this.task = task;
        }

        void runTask(){
            lastTaskTimestamp = System.currentTimeMillis();
            task.run();
            isRunning = false;
            thread = null;
        }
    }



    public interface OnMultiClickListener {

        void onClick(View view);

        void onDoubleClick(View view);

        void onTrebleClick(View view);

        void on2Click(View view);

        void on2DoubleClick(View view);

        void on2TrebleClick(View view);

        void on3Click(View view);

        void on3DoubleClick(View view);

        void on3TrebleClick(View view);

        void on4Click(View view);

        void on4DoubleClick(View view);

        void on4TrebleClick(View view);

    }
}
